using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using TALoaders;
using TAAlert.CommonUtils;

namespace TAAlert.GUI
{
    public partial class GetBackTestParametersGUI : Form
    {
        private static readonly TraceSwitch traceM = new TraceSwitch("BackTestGUI", "Debug messages in GUI EMA BackTest");
        private static readonly string CLB_MONTHLY = "Monthly"; // used in CheckedLIstBox
        private static readonly string CLB_YEARLY = "Yearly";   // used in CheckedListBox

        /// <summary>if True then perform TwoEMA back-test. If False perform single EMA back-test</summary>
        private StrategyName strategyM;

        public GetBackTestParametersGUI(StrategyName strategy)
        {
            InitializeComponent();
            this.strategyM = strategy;
            this.lblTitle.Text = strategy.ToString();

            // Add available loaders
            foreach (string loaderName in Enum.GetNames(typeof(Loader)))
                this.cbLoadersM.Items.Add(loaderName);
            this.cbLoadersM.SelectedIndex = (int)Loader.Yahoo;
            this.clbIntraPeriodM.Items.Add(CLB_YEARLY, true);
            this.clbIntraPeriodM.Items.Add(CLB_MONTHLY, false);
            // Signal Quote Types:
            this.cbSigQuoteTypeM.Items.Add(QuoteType.AdjClose.ToString());
            this.cbSigQuoteTypeM.SelectedIndex = 0;
            this.cbSigQuoteTypeM.Items.Add(QuoteType.AvgHL.ToString());
            this.cbSigQuoteTypeM.Items.Add(QuoteType.AvgHLC.ToString());
            
            // Set-up corect input fields
            this.tbTransactionCostM.Text = Convert.ToString(0.003);
            switch (this.strategyM)
            {
                case StrategyName.EMA:
                    this.lbShortM.Visible = false;
                    this.lbLongM.Visible = false;
                    this.tbnLongMinM.Visible = false;
                    this.tbnLongMaxM.Visible = false;
                    this.tbLongStepM.Visible = false;
                    this.lbFast.Visible = false;
                    this.tbFastMinM.Visible = false;
                    this.tbFastMaxM.Visible = false;
                    this.tbFastStepM.Visible = false;
                    break;
                case StrategyName.TwoEMA:
                    this.tbnMinM.Text = "5";
                    this.tbnMaxM.Text = "20";
                    this.tbShortStepM.Text = "5";
                    this.tbnLongMinM.Text = "30";
                    this.tbnLongMaxM.Text = "60";
                    this.tbLongStepM.Text = "10";
                    this.lbFast.Text = "Vol";
                    this.tbFastMinM.Text = Convert.ToString(0.20);
                    this.tbFastMaxM.Text = Convert.ToString(0.50);
                    this.tbFastStepM.Text = Convert.ToString(0.10);
                    break;
                case StrategyName.MACD:
                    break;
                case StrategyName.VEMA:
                    this.lbShortM.Text = "nLowVol";
                    this.tbnMinM.Text = "5";
                    this.tbnMaxM.Text = "50";
                    this.tbShortStepM.Text = "5";
                    this.lbLongM.Text = "nHighVol";
                    this.tbnLongMinM.Text = "30";
                    this.tbnLongMaxM.Text = "180";
                    this.tbLongStepM.Text = "10";
                    this.lbFast.Text = "Vol";
                    this.tbFastMinM.Text = Convert.ToString(0.20);
                    this.tbFastMaxM.Text = Convert.ToString(0.50);
                    this.tbFastStepM.Text = Convert.ToString(0.10);
                    break;
                default:
                    throw new Exception("GetBackTestParametersGUI: unknown strategy " + strategyM.ToString());
            }
        }

        private void cbLoadersM_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.cbTickersM.Items.Clear();
            string[] tickers = TALoaders.DownloaderFactory.getDefaultTickers(this.cbLoadersM.SelectedItem.ToString());

            foreach (string ticker in tickers)
                this.cbTickersM.Items.Add(ticker);
            this.cbTickersM.SelectedIndex = 0;
        }

        private void btGenerateBackTest_Click(object sender, EventArgs e)
        {
            DateTime startDate = this.dtStartDatePickerM.Value.Date;
            DateTime endDate = this.dtEndDatePickerM.Value.Date;
            string loaderName = this.cbLoadersM.SelectedItem.ToString();
            string ticker = cbTickersM.Text;

            bool showYearlyPerf = clbIntraPeriodM.CheckedItems.IndexOf(CLB_YEARLY) != -1;
            bool showMonthlyPerf = clbIntraPeriodM.CheckedItems.IndexOf(CLB_MONTHLY) != -1;
            string sigQuoteTypeString = cbSigQuoteTypeM.SelectedItem.ToString();
            QuoteType sigType = (QuoteType)Enum.Parse(typeof(QuoteType), sigQuoteTypeString);

            int nShortMin, nShortMax, shortStep, nLongMIN, nLongMAX, longStep;
            double nFastMIN, nFastMAX, fastStep;
            double transactionCost;
            if (Int32.TryParse(this.tbnMinM.Text, out nShortMin) &&
                Int32.TryParse(this.tbnMaxM.Text, out nShortMax) &&
                Int32.TryParse(this.tbnLongMinM.Text, out nLongMIN) &&
                Int32.TryParse(this.tbnLongMaxM.Text, out nLongMAX) &&
                Double.TryParse(this.tbFastMinM.Text, out nFastMIN) &&
                Double.TryParse(this.tbFastMaxM.Text, out nFastMAX) &&
                Double.TryParse(this.tbTransactionCostM.Text, out transactionCost) &&
                Int32.TryParse(this.tbShortStepM.Text, out shortStep) &&
                Int32.TryParse(this.tbLongStepM.Text, out longStep) &&
                Double.TryParse(this.tbFastStepM.Text, out fastStep) &&
                ticker.Length > 0 &&
                startDate < endDate &&
                loaderName.Length > 0)
            {
                BackTestGUI btGUI;
                switch (this.strategyM)
                {
                    case StrategyName.EMA:
                        Debug.WriteLineIf(traceM.TraceInfo, "Starting (single) EMA back-test with startDate=" + startDate.ToShortDateString() +
                                ", endDate=" + endDate.ToShortDateString() + ", loader=" + loaderName + ", ticker=" + ticker +
                                ", nMIN=" + nShortMin + ", nMAX=" + nShortMax + ", nSTEP=" + shortStep +
                                ", yearly=" + showYearlyPerf + ", monthly=" + showMonthlyPerf + ", transCost=" + transactionCost +
                                ", type=" + sigQuoteTypeString);
                        btGUI = new BackTestGUI(ticker, loaderName, startDate, endDate, nShortMin, nShortMax, shortStep, showYearlyPerf, showMonthlyPerf, transactionCost, sigType);
                        break;
                    case StrategyName.MACD:
                        Debug.WriteLineIf(traceM.TraceInfo, "Starting MACD back-test with startDate=" + startDate.ToShortDateString() +
                                 ", endDate=" + endDate.ToShortDateString() + ", loader=" + loaderName + ", ticker=" + ticker +
                                 ", nShortMIN=" + nShortMin + ", nShortMAX=" + nShortMax + ", shortSTEP=" + shortStep +
                                 ", nLongMIN=" + nLongMIN + ", nLongMAX=" + nLongMAX + ", longSTEP=" + longStep +
                                 ", nFaseMIN=" + nFastMIN + ", nFastMAX=" + nFastMAX + ", fastSTEP=" + fastStep +
                                 ", yearly=" + showYearlyPerf + ", monthly=" + showMonthlyPerf + ", transCost=" + transactionCost +
                                 ", type=" + sigQuoteTypeString);
                        btGUI = new BackTestGUI(ticker, loaderName, startDate, endDate, nShortMin, nShortMax, shortStep, nLongMIN, nLongMAX, longStep, (int)nFastMIN, (int)nFastMAX, (int)fastStep, showYearlyPerf, showMonthlyPerf, transactionCost, sigType);
                        break;
                    case StrategyName.TwoEMA:
                        Debug.WriteLineIf(traceM.TraceInfo, "Starting TwoEMA back-test with startDate=" + startDate.ToShortDateString() +
                                 ", endDate=" + endDate.ToShortDateString() + ", loader=" + loaderName + ", ticker=" + ticker +
                                 ", nShortMIN=" + nShortMin + ", nShortMAX=" + nShortMax + ", shortSTEP=" + shortStep +
                                 ", nLongMIN=" + nLongMIN + ", nLongMAX=" + nLongMAX + ", longSTEP=" + longStep +
                                 ", volMIN=" + nFastMIN + ", volMAX=" + nFastMAX + ", volSTEP=" + fastStep +
                                 ", yearly=" + showYearlyPerf + ", monthly=" + showMonthlyPerf + ", transCost=" + transactionCost +
                                 ", type=" + sigQuoteTypeString);
                        btGUI = new BackTestGUI(StrategyName.TwoEMA, ticker, loaderName, startDate, endDate, nShortMin, nShortMax, shortStep, nLongMIN, nLongMAX, longStep, nFastMIN, nFastMAX, fastStep, showYearlyPerf, showMonthlyPerf, transactionCost, sigType);
                        break;
                    case StrategyName.VEMA:
                        Debug.WriteLineIf(traceM.TraceInfo, "Starting VEMA back-test with startDate=" + startDate.ToShortDateString() +
                                 ", endDate=" + endDate.ToShortDateString() + ", loader=" + loaderName + ", ticker=" + ticker +
                                 ", nShortMIN=" + nShortMin + ", nShortMAX=" + nShortMax + ", shortSTEP=" + shortStep +
                                 ", nLongMIN=" + nLongMIN + ", nLongMAX=" + nLongMAX + ", longSTEP=" + longStep +
                                 ", volMIN=" + nFastMIN + ", volMAX=" + nFastMAX + ", volSTEP=" + fastStep +
                                 ", yearly=" + showYearlyPerf + ", monthly=" + showMonthlyPerf + ", transCost=" + transactionCost +
                                 ", type=" + sigQuoteTypeString);
                        btGUI = new BackTestGUI(StrategyName.VEMA, ticker, loaderName, startDate, endDate, nShortMin, nShortMax, shortStep,nLongMIN, nLongMAX, longStep, nFastMIN, nFastMAX, fastStep, showYearlyPerf, showMonthlyPerf, transactionCost, sigType);
                        break;
                    default:
                        throw new Exception("GetBackTestStrategy: unrecognized strategy " + strategyM.ToString());
                }
                Thread btThread = new Thread(this.doShowBackTestGUIInNewThread);
                btThread.Start(btGUI);
                this.quit_Click(sender, e);
            }
            else
                Debug.WriteLineIf(traceM.TraceError, "Cannot parse input FORM arguments");
        }

        private void doShowBackTestGUIInNewThread(object btGUIObject)
        {
            BackTestGUI btGUI = (BackTestGUI)btGUIObject;
            btGUI.ShowDialog();
        }

        private void quit_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}